package com.example.casper.Experiment2024.ui.activity;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
import static androidx.test.espresso.action.ViewActions.replaceText;
import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withClassName;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertTrue;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.ImageView;

import androidx.test.espresso.UiController;
import androidx.test.espresso.ViewAction;
import androidx.test.espresso.ViewInteraction;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;

import com.example.casper.Experiment2024.R;
import com.example.casper.Experiment2024.activity.Hello2249Activity;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
// helloworld
@LargeTest
@RunWith(AndroidJUnit4.class)
public class Hello2249ActivityTest {
    // 定义Activity测试规则，用于启动Hello2249Activity并管理其生命周期

    @Rule
    public ActivityScenarioRule<Hello2249Activity> activityRule =
            new ActivityScenarioRule<>(Hello2249Activity.class);

    @Test
    public void testHelloActivity() {
        // 查找RecyclerView控件

        ViewInteraction recyclerView = onView(
                allOf(withId(R.id.recycler_view_the_books),
                        atPositionInParent(
                                withClassName(is("androidx.constraintlayout.widget.ConstraintLayout")),
                                0)));
        // 查找价格编辑框，并将其文本替换为“100”

        ViewInteraction editTextTitle = onView(
                allOf(withId(android.R.id.title), withText("修改"),
                        atPositionInParent(
                                atPositionInParent(
                                        withId(android.R.id.content),
                                        0),
                                0),
                        isDisplayed()));
        editTextTitle.perform(click());

        ViewInteraction priceEditText = onView(
                allOf(withId(R.id.edittext_item_price), withText("1.0"),
                        atPositionInParent(
                                atPositionInParent(
                                        withId(android.R.id.content),
                                        0),
                                3),
                        isDisplayed()));
        priceEditText.perform(replaceText("100"));

        ViewInteraction priceEditText2 = onView(
                allOf(withId(R.id.edittext_item_price), withText("100"),
                        atPositionInParent(
                                atPositionInParent(
                                        withId(android.R.id.content),
                                        0),
                                3),
                        isDisplayed()));
        priceEditText2.perform(closeSoftKeyboard());

        // Verify image
        Bitmap firstBitmap = BitmapFactory.decodeResource(
                InstrumentationRegistry.getInstrumentation().getTargetContext().getResources(),
                R.drawable.book_1
        );
        Bitmap secondBitmap = BitmapFactory.decodeResource(
                InstrumentationRegistry.getInstrumentation().getTargetContext().getResources(),
                R.drawable.book_1_1
        );

        assertTrue(areBitmapsIdentical(firstBitmap, secondBitmap));
    }

    /**
     * 从指定的ImageView中提取Bitmap。
     *
     * @param imageViewId 需要提取Bitmap的ImageView的ID
     * @return 从ImageView中提取到的Bitmap
     */
    private Bitmap extractBitmapFromImageView(int imageViewId) {
        final Bitmap[] extractedBitmap = new Bitmap[1];
        onView(withId(imageViewId)).perform(new ViewAction() {
            @Override
            public Matcher<View> getConstraints() {
                return isAssignableFrom(ImageView.class);
            }

            @Override
            public String getDescription() {
                return "Extract bitmap from ImageView";
            }

            @Override
            public void perform(final UiController uiController, final View view) {
                ImageView imageView = (ImageView) view;
                extractedBitmap[0] = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
            }
        });
        return extractedBitmap[0];
    }
    /**
     * 比较两张Bitmap是否完全相同。
     *
     * @param firstBitmap 第一张Bitmap
     * @param secondBitmap 第二张Bitmap
     * @return 如果两张Bitmap的尺寸和每个像素都相同，则返回true，否则返回false
     */
    private boolean areBitmapsIdentical(Bitmap firstBitmap, Bitmap secondBitmap) {
        if (firstBitmap.getWidth() != secondBitmap.getWidth() || firstBitmap.getHeight() != secondBitmap.getHeight()) {
            return false;
        }
        for (int x = 0; x < firstBitmap.getWidth(); x++) {
            for (int y = 0; y < firstBitmap.getHeight(); y++) {
                if (firstBitmap.getPixel(x, y) != secondBitmap.getPixel(x, y)) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 创建一个自定义的Matcher，用来匹配父视图中的指定位置的子视图。
     *
     * @param parentMatcher 父视图的Matcher
     * @param position 目标位置的索引
     * @return 匹配指定位置子视图的Matcher
     */
    private static Matcher<View> atPositionInParent(
            final Matcher<View> parentMatcher, final int position) {

        return new TypeSafeMatcher<View>() {
            @Override
            public void describeTo(Description description) {
                description.appendText("Child at position " + position + " in parent ");
                parentMatcher.describeTo(description);
            }

            @Override
            public boolean matchesSafely(View view) {
                ViewParent parent = view.getParent();
                return parent instanceof ViewGroup && parentMatcher.matches(parent)
                        && view.equals(((ViewGroup) parent).getChildAt(position));
            }
        };
    }
}
